package com.youhome.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by chen365 on 2018/12/07.
 */
@Slf4j
@Component
public class TokenUtils implements Serializable {
    private static final long JWT_EXPIRY_DATE = 30 * 60 * 1000; //(s) token 有效期 30 分种
    private static final String JWT_SECRET = "s9*KKss21%#56**&xG"; //密钥
    private static final String JWT_SUBJECT = "HOME"; //主题
    private static final String JWT_ISSUER = "YOU-HOME"; //发行人
    private static final String JWT_AUDIENCE = "LOGIN"; //受众

    private static final String pattern = "yyyy-MM-dd HH:mm:ss";

    /**
     * 生成Key
     * 该方法使用HS256算法和Secret:bankgl生成signKey
     *
     * @return
     */
//    private static Key getKeyInstance() {
//        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
//        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(JWT_SECRET);
//        Key signingKey = new SecretKeySpec(apiKeySecretBytes, signatureAlgorithm.getJcaName());
//        return signingKey;
//    }

    /**
     * 生成Token
     * 使用HS256签名算法和生成的signingKey最终的Token,claims中是有效载荷
     *
     * @param map
     * @return
     */
    public static String createToken(Map<String, Object> map) {
        Date expireDate = getExpireDate();

        System.err.println("expiration:" + DateFormatUtils.format(expireDate, pattern));

        String token = Jwts.builder()
                .setSubject(JWT_SUBJECT)//设置抽象主题
                .setIssuer(JWT_ISSUER)//设置发行人
                .setAudience(JWT_AUDIENCE)//设置受众
                .setIssuedAt(new Date())//设置现在时间
                .setClaims(map)
                .setExpiration(expireDate)//过期时间
                .signWith(SignatureAlgorithm.HS512, JWT_SECRET)
                .compact();
        return token;
    }

    /**
     * 获取过期时间
     *
     * @return
     */
    public static Date getExpireDate() {
        long time = System.currentTimeMillis();
        time += JWT_EXPIRY_DATE;
        Date date = new Date(time);
        System.err.println("date:" + DateFormatUtils.format(date, pattern));
        return date;
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims parserToken(String token) {
        try {
            return Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(token).getBody();
        } catch (Exception e) {
            log.error("json web token verify failed");
        }
        return null;
    }

    /**
     * 判断令牌是否过期
     *
     * @param token 令牌
     * @return 是否过期
     */
    public static Boolean isExpired(String token) {
        System.err.println("isExpired");
        try {
            Claims claims = parserToken(token);
            if (claims.isEmpty()) {
                System.err.println("claims is null");
                return false;
            }
            Date expiration = claims.getExpiration();
            if (StringUtils.isEmpty(expiration)) {
                System.err.println("expiration is null");
                return false;
            }
            System.err.println("expiration:" + DateFormatUtils.format(expiration, pattern));
            System.err.println(expiration);
            return expiration.after(new Date());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 从 token 里获取 openid
     * @param token
     * @return
     */
    public static String getOpenIdByToken(String token) {
        Claims claims = parserToken(token);
        if (claims.isEmpty()) {
            return null;
        }
        Object openid = claims.get("openid");
        if (StringUtils.isEmpty(openid)) {
            return null;
        }
        return (String) openid;
    }


    public static void main(String[] args) {
//        String token = "eyJhbGciOiJIUzI1NiJ9.eyJvcGVuaWQiOiJveHVpbDVESnFvM0QzYUt6bTNQWklqdVpsYXN3In0.a7Re8C3HXkBo4u5SFptFXrREkAi9LGNDlHCg4BezsW4";
//        Boolean tokenExpired = isExpired(token);
//        System.err.println(tokenExpired);


        Map<String, Object> map = new HashMap<>();
        map.put("openid", "1111111");

        String s = createToken(map);
        System.err.println(s);

        Boolean tokenExpired = isExpired(s);

        System.err.println(tokenExpired);


    }
}
